/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.service.grant.role.impl;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.beust.jcommander.internal.Lists;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.je.auth.check.exception.NotOrgException;
import com.je.common.base.DynaBean;
import com.je.common.base.context.GlobalExtendedContext;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.mapper.query.Query;
import com.je.common.base.mvc.BaseMethodArgument;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaResourceService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.util.*;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.rpc.setting.MetaSystemSettingRpcService;
import com.je.rbac.cache.AccountPermissionCache;
import com.je.rbac.cache.AccountProductCache;
import com.je.rbac.exception.AccountException;
import com.je.rbac.exception.RoleException;
import com.je.rbac.service.account.RbacAccountService;
import com.je.rbac.service.company.RbacUserService;
import com.je.rbac.service.grant.org.RbacGrantOrgService;
import com.je.rbac.service.grant.role.RbacGrantRoleService;
import com.je.rbac.service.organization.OrgType;
import com.je.rbac.service.permission.PermissionLoadService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static com.je.rbac.service.role.impl.RbacRoleServiceImpl.*;
import static com.je.rbac.service.threemember.impl.ThreeMemberSettingServiceImpl.*;

@Service
public class RbacGrantRoleServiceImpl implements RbacGrantRoleService {

    private static final Logger logger = LoggerFactory.getLogger(RbacGrantRoleServiceImpl.class);

    @Autowired
    private MetaService metaService;
    @Autowired
    private BeanService beanService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private MetaSystemSettingRpcService metaSystemSettingRpcService;
    @Autowired
    private AccountPermissionCache accountPermissionCache;
    @Autowired
    private AccountProductCache accountProductCache;
    @Autowired
    private MetaResourceService metaResourceService;
    @Autowired
    private RbacUserService rbacUserService;
    @Autowired
    private RbacAccountService rbacAccountService;
    @Autowired
    private RbacGrantOrgService rbacGrantOrgService;
    @Autowired
    private PermissionLoadService permissionLoadService;

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, RoleException.class})
    public DynaBean insertFolder(String folderName, String iconCls, String remark, boolean develop) {
        List<Map<String, Object>> countList = metaService.selectSql("SELECT MAX(SY_ORDERINDEX) AS MAX_COUNT FROM JE_RBAC_ROLE");
        int count = (int) countList.get(0).get("MAX_COUNT");
        int currentChildCount = 0;
        List<Map<String, Object>> currentChildList = metaService.selectSql("SELECT MAX(SY_ORDERINDEX) AS TOTAL_COUNT FROM JE_RBAC_ROLE WHERE SY_PARENT = {0}", "ROOT");
        if (currentChildList != null && currentChildList.size() > 0) {
            currentChildCount = (int) currentChildList.get(0).get("TOTAL_COUNT");
        }
        String folderId = JEUUID.uuid();
        DynaBean folderBean = new DynaBean("JE_RBAC_ROLE", false);
        folderBean.set("JE_RBAC_ROLE_ID", folderId);
        folderBean.set("ROLE_NAME", folderName);
        folderBean.set("ROLE_CODE", "folder-role-" + String.format("%06d", count));
        folderBean.set("ROLE_TYPE_CODE", FOLDER_TYPE_CODE);
        folderBean.set("ROLE_TYPE_NAME", FOLDER_TYPE_NAME);
        folderBean.set("ROLE_REMARK", remark);
        //树形节点值
        folderBean.set("SY_PARENT", "ROOT");
        folderBean.set("SY_PARENTPATH", "/ROOT");
        folderBean.set("SY_LAYER", 1);
        folderBean.set("SY_STATUS", "1");
        folderBean.set("SY_NODETYPE", "GENERAL");
        folderBean.set("SY_PATH", "/ROOT/" + folderId);
        folderBean.set("SY_TREEORDERINDEX", "000001" + String.format("%06d", currentChildCount + 1));
        //创建时间
        folderBean.set("SY_CREATETIME", DateUtils.formatDateTime(new Date()));
        folderBean.set("ROLE_ICONCLS", iconCls);
        folderBean.set("ROLE_DEVELOP", develop ? "1" : "0");
        folderBean.set("SY_ORDERINDEX", count + 1);
        metaService.insert(folderBean);
        return folderBean;
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, RoleException.class})
    public void updateFolder(String folderId, String folderName) {
        metaService.executeSql("UPDATE JE_RBAC_ROLE SET ROLE_NAME = {0} WHERE JE_RBAC_ROLE_ID = {1}", folderName, folderId);
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, RoleException.class})
    public void removeFolder(String folderId) throws RoleException {
        long count = metaService.countBySql("SELECT JE_RBAC_ROLE_ID FROM JE_RBAC_ROLE WHERE SY_PARENT = {0}", folderId);
        if (count > 0) {
            throw new RoleException("文件夹下存在角色，请先移除角色！");
        }
        metaService.delete("JE_RBAC_ROLE", ConditionsWrapper.builder().eq("JE_RBAC_ROLE_ID", folderId));
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, RoleException.class})
    public DynaBean insertRole(String parentRoleId, String roleName, String permGroupIds, String permGroupNames, String baseRoleId, String iconCls, String remark, boolean develop) throws RoleException {
        //如果没有父角色，则父节点为根节点,如果存在，则树形路径的基础路径为父路径下追加
        if (Strings.isNullOrEmpty(parentRoleId)) {
            parentRoleId = "ROOT";
        } else {
            metaService.executeSql("UPDATE JE_RBAC_ROLE SET SY_NODETYPE='GENERAL' WHERE JE_RBAC_ROLE_ID = {0}", parentRoleId);
        }

        List<Map<String, Object>> countList = metaService.selectSql("SELECT MAX(SY_ORDERINDEX) AS MAX_COUNT FROM JE_RBAC_ROLE");
        int count = (int) countList.get(0).get("MAX_COUNT");
        DynaBean parent = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder().eq("JE_RBAC_ROLE_ID", parentRoleId));
        if (parent == null) {
            throw new RoleException("不存在的父角色，请确认父角色存在！");
        }
        int currentChildCount = 0;
        List<Map<String, Object>> currentChildList = metaService.selectSql("SELECT MAX(SY_ORDERINDEX) AS TOTAL_COUNT FROM JE_RBAC_ROLE WHERE SY_PARENT = {0}", parentRoleId);
        if (currentChildList != null && currentChildList.size() > 0) {
            currentChildCount = (int) currentChildList.get(0).get("TOTAL_COUNT");
        }
        String roleId = JEUUID.uuid();
        DynaBean roleBean = new DynaBean("JE_RBAC_ROLE", false);
        roleBean.set("JE_RBAC_ROLE_ID", roleId);
        roleBean.set("ROLE_NAME", roleName);
        roleBean.set("ROLE_CODE", "role-" + String.format("%06d", count + 1));
        roleBean.set("ROLE_TYPE_CODE", ROLE_TYPE_CODE);
        roleBean.set("ROLE_TYPE_NAME", ROLE_TYPE_NAME);
        roleBean.set("ROLE_REMARK", remark);
        roleBean.set("ROLE_ICONCLS", iconCls);
        roleBean.set("ROLE_PERMGROUP_ID", permGroupIds);
        roleBean.set("ROLE_PERMGROUP_NAME", permGroupNames);
        if (!Strings.isNullOrEmpty(baseRoleId)) {
            DynaBean baseRoleBean = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder().eq("JE_RBAC_ROLE_ID", baseRoleId));
            if (baseRoleBean == null) {
                throw new RoleException("不存在的基础角色，请确认基础角色存在！");
            }
            roleBean.set("ROLE_BASE_ID", baseRoleId);
            roleBean.set("ROLE_BASE_NAME", baseRoleBean.getStr("ROLE_NAME"));
        }

        //树形节点值
        roleBean.set("SY_PARENT", parent.getStr("JE_RBAC_ROLE_ID"));
        roleBean.set("SY_PARENTPATH", parent.getStr("SY_PATH"));
        roleBean.set("SY_LAYER", parent.getInt("SY_LAYER") + 1);
        roleBean.set("SY_STATUS", "1");
        roleBean.set("SY_NODETYPE", "LEAF");
        roleBean.set("SY_PATH", parent.getStr("SY_PATH") + "/" + roleId);
        roleBean.set("SY_TREEORDERINDEX", parent.getStr("SY_TREEORDERINDEX") + String.format("%06d", currentChildCount + 1));
        //创建时间
        roleBean.set("SY_CREATETIME", DateUtils.formatDateTime(new Date()));
        roleBean.set("ROLE_DEVELOP", develop ? "1" : "0");
        roleBean.set("SY_ORDERINDEX", count + 1);
        metaService.insert(roleBean);
        return roleBean;
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, RoleException.class})
    public void updateRole(String roleId, String roleName, String permGroupIds, String permGroupNames, String baseRoleId, String remark) throws RoleException {
        Boolean updateReferencesRoleName = false;
        DynaBean roleBean = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder().eq("JE_RBAC_ROLE_ID", roleId));
        if (roleBean == null) {
            throw new RoleException("不存在此角色，请确认此角色存在！");
        }
        if (!roleBean.getStr("ROLE_NAME").equals(roleName)) {
            updateReferencesRoleName = true;
        }
        roleBean.set("ROLE_NAME", roleName);
        if (!Strings.isNullOrEmpty(baseRoleId)) {
            DynaBean baseRoleBean = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder().eq("JE_RBAC_ROLE_ID", baseRoleId));
            if (baseRoleBean == null) {
                throw new RoleException("不存在的基础角色，请确认基础角色存在！");
            }
            roleBean.set("ROLE_BASE_ID", baseRoleId);
            roleBean.set("ROLE_BASE_NAME", baseRoleBean.getStr("ROLE_NAME"));
        }

        roleBean.set("ROLE_PERMGROUP_ID", permGroupIds);
        roleBean.set("ROLE_PERMGROUP_NAME", permGroupNames);

        if (remark != null) {
            roleBean.set("ROLE_REMARK", remark);
        }
        metaService.update(roleBean);
        if (updateReferencesRoleName) {
            syncUpdateReferencesRoleName(roleId, roleName);
        }
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, RoleException.class})
    public void removeRole(String roleId) throws RoleException {
        permissionLoadService.removeRolePermCache(Lists.newArrayList(roleId));
        permissionLoadService.removeDevelopRolePermCache(Lists.newArrayList(roleId));
        long count = metaService.countBySql("SELECT JE_RBAC_ROLE_ID FROM JE_RBAC_ROLE WHERE SY_PARENT = {0}", roleId);
        if (count > 0) {
            throw new RoleException("文件夹下存在角色，请先移除角色！");
        }
        //删除账户配置
        deleteRoleAccountConfigByRoleId(roleId);
        //删除权限配置
        metaService.delete("JE_RBAC_ROLEPERM", ConditionsWrapper.builder().eq("JE_RBAC_ROLE_ID", roleId));
        //删除角色
        metaService.delete("JE_RBAC_ROLE", ConditionsWrapper.builder().eq("JE_RBAC_ROLE_ID", roleId));
    }

    private void deleteRoleAccountConfigByRoleId(String roleId) {
        List<DynaBean> orgList = metaService.select("JE_RBAC_ACCOUNTROLE", ConditionsWrapper.builder().eq("ACCOUNTROLE_ROLE_ID", roleId));
        for (DynaBean dynaBean : orgList) {
            String accountId = dynaBean.getStr("ACCOUNTROLE_ACCOUNT_ID");
            removeAccountRole(roleId, dynaBean.getStr("ACCOUNTROLE_DEPT_ID"), Splitter.on(",").splitToList(accountId));
            accountPermissionCache.removeCache(dynaBean.getStr("ACCOUNTROLE_ACCOUNT_ID"));
            accountProductCache.removeCache(dynaBean.getStr("ACCOUNTROLE_ACCOUNT_ID"));
        }
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, RoleException.class})
    public void move(String roleId, String targetParentId, Integer order, boolean develop) throws RoleException {
        DynaBean role = metaService.selectOneByPk("JE_RBAC_ROLE", roleId);
        if (Strings.isNullOrEmpty(targetParentId)) {
            targetParentId = "ROOT";
        }
        if (FOLDER_TYPE_CODE.equals(role.getStr("ROLE_TYPE_CODE")) && !"ROOT".equals(targetParentId)) {
            throw new RoleException("文件夹类型只能存在于根节点下！");
        }

        List<DynaBean> operationList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .like("SY_PATH", roleId)
                .ne("JE_RBAC_ROLE_ID", roleId)
                .orderByAsc("SY_TREEORDERINDEX"));

        //----------------源父节点及其子节点更新----------------
        if (!targetParentId.equals(role.getStr("SY_PARNET"))) {
            //如果源父节点是ROOT节点，则不做处理
            DynaBean originParentBean = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder()
                    .eq("JE_RBAC_ROLE_ID", role.getStr("SY_PARENT"))
                    .orderByAsc("SY_TREEORDERINDEX"));
            sourceCalcAndUpdate(originParentBean, role, operationList, develop);
        }

        //----------------目标节点及目标节点的子节点更新----------------
        DynaBean targetRole = metaService.selectOneByPk("JE_RBAC_ROLE", targetParentId);
        targetCalcAndUpdate(targetRole, role, operationList, order, develop);
    }

    /**
     * 放置到目标节点的操作
     *
     * @param parentBean
     * @param operationRootBean
     * @param operationList
     * @param order
     */
    private void targetCalcAndUpdate(DynaBean parentBean, DynaBean operationRootBean, List<DynaBean> operationList, Integer order, boolean develop) {
        List<String> notInOperatorIdList = new ArrayList<>();
        notInOperatorIdList.add(operationRootBean.getStr("JE_RBAC_ROLE_ID"));
        for (DynaBean eachOperatorBean : operationList) {
            notInOperatorIdList.add(eachOperatorBean.getStr("JE_RBAC_ROLE_ID"));
        }
        List<DynaBean> childrenBeanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .eq("ROLE_DEVELOP", develop ? "1" : "0")
                .ne("JE_RBAC_ROLE_ID", parentBean.getStr("JE_RBAC_ROLE_ID"))
                .like("SY_PATH", parentBean.getStr("JE_RBAC_ROLE_ID"))
                .notIn("JE_RBAC_ROLE_ID", notInOperatorIdList)
                .orderByAsc("SY_TREEORDERINDEX"));

        //待排list
        List<DynaBean> needOrderBeanList = new ArrayList<>();
        List<DynaBean> otherBeanList = new ArrayList<>();
        for (DynaBean eachBean : childrenBeanList) {
            if (eachBean.getStr("SY_PARENT").equals(parentBean.get("JE_RBAC_ROLE_ID"))) {
                needOrderBeanList.add(eachBean);
            } else {
                otherBeanList.add(eachBean);
            }
        }

        //如果是移入操作，则设置操作对象的父节点，并加入子对象集合
        operationRootBean.set("SY_PARENT", parentBean.getStr("JE_RBAC_ROLE_ID"));
        if (order == null) {
            needOrderBeanList.add(operationRootBean);
        } else {
            needOrderBeanList.add(order, operationRootBean);
        }

        needOrderBeanList.addAll(otherBeanList);
        needOrderBeanList.addAll(operationList);

        //递归设置树形属性
        recursiveCalcChildrenTreeNode(parentBean, needOrderBeanList);
        //更新
        for (DynaBean eachChildBean : needOrderBeanList) {
            metaService.update(eachChildBean);
        }
    }

    /**
     * 递归设置计算树形子节点信息并返回，需要重新计算的树形有layer,treeOrderIndex
     *
     * @param parentBean    父节点bean
     * @param childrenBeans 所有子孙节点
     */
    private void recursiveCalcChildrenTreeNode(DynaBean parentBean, List<DynaBean> childrenBeans) {
        if (childrenBeans == null || childrenBeans.isEmpty()) {
            return;
        }

        List<DynaBean> children = new ArrayList<>();
        for (DynaBean eachBean : childrenBeans) {
            if (parentBean.getStr("JE_RBAC_ROLE_ID").equals(eachBean.getStr("SY_PARENT"))) {
                children.add(eachBean);
            }
        }

        if (children.isEmpty()) {
            parentBean.set("SY_NODETYPE", "LEAF");
            return;
        }

        //主键递归下找并设置当前子节点树形
        parentBean.set("SY_NODETYPE", "GENERAL");
        String parentTreeOrderIndex = parentBean.getStr("SY_TREEORDERINDEX");
        int layer = parentBean.getInt("SY_LAYER");
        String parentPath = parentBean.getStr("SY_PATH");

        for (int i = 0; i < children.size(); i++) {
            children.get(i).set("SY_LAYER", layer + 1);
            children.get(i).set("SY_PATENTPATH", parentPath);
            children.get(i).set("SY_PATH", parentPath + "/" + children.get(i).getStr("JE_RBAC_ROLE_ID"));
            children.get(i).set("SY_TREEORDERINDEX", parentTreeOrderIndex + String.format("%06d", i + 1));
            recursiveCalcChildrenTreeNode(children.get(i), childrenBeans);
        }

    }

    /**
     * 源对象集合操作
     *
     * @param parentBeaen
     * @param operationRootBean
     * @param operationList
     */
    private void sourceCalcAndUpdate(DynaBean parentBeaen, DynaBean operationRootBean, List<DynaBean> operationList, boolean develop) {
        List<DynaBean> childrenBeanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .eq("ROLE_DEVELOP", develop ? "1" : "0")
                .eq("SY_PARENT", parentBeaen.getStr("JE_RBAC_ROLE_ID"))
                .or().likeRight("SY_PATH", parentBeaen.getStr("JE_RBAC_ROLE_ID"))
                .orderByAsc("SY_TREEORDERINDEX"));

        //如果是移除操作，则去除操作对象
        List<DynaBean> needRemovedList = new ArrayList<>();
        for (DynaBean eachBean : childrenBeanList) {
            if (eachBean.getStr("JE_RBAC_ROLE_ID").equals(operationRootBean.getStr("JE_RBAC_ROLE_ID"))) {
                needRemovedList.add(eachBean);
            }
            for (DynaBean eachOperationBean : operationList) {
                if (eachBean.getStr("JE_RBAC_ROLE_ID").equals(eachOperationBean.getStr("JE_RBAC_ROLE_ID"))) {
                    needRemovedList.add(eachBean);
                }
            }
        }
        childrenBeanList.remove(needRemovedList);

        //递归设置树形属性
        recursiveCalcChildrenTreeNode(parentBeaen, childrenBeanList);
        //更新
        for (DynaBean eachChildBean : childrenBeanList) {
            metaService.update(eachChildBean);
        }
    }

    @Override
    public JSONTreeNode buildRoleTree(boolean develop, String... roleOrFolderIds) {
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        DynaBean table = beanService.getResourceTable("JE_RBAC_ROLE");
        List<DynaBean> columns = (List<DynaBean>) table.get(BeanService.KEY_TABLE_COLUMNS);
        JSONTreeNode template = beanService.buildJSONTreeNodeTemplate(columns);
        String accountId = SecurityUserHolder.getCurrentAccountId();
        List<DynaBean> accountDeptBeanList = metaService.select("JE_RBAC_ACCOUNTDEPT", ConditionsWrapper.builder().eq("ACCOUNTDEPT_ACCOUNT_ID", accountId));
        List<String> accountDeptIdList = new ArrayList<>();
        for (int i = 0; accountDeptBeanList != null && !accountDeptBeanList.isEmpty() && i < accountDeptBeanList.size(); i++) {
            accountDeptIdList.add(accountDeptBeanList.get(i).getStr("JE_RBAC_ACCOUNTDEPT_ID"));
        }

        List<DynaBean> productList = metaResourceService.selectByTableCodeAndNativeQuery("JE_PRODUCT_MANAGE", NativeQuery.build());
        List<String> productIdList = new ArrayList<>();
        List<String> developerIdList;
        for (DynaBean eachProductBean : productList) {
            if (!Strings.isNullOrEmpty(eachProductBean.getStr("PRODUCT_DEVELOPER_ID"))) {
                developerIdList = Splitter.on(",").splitToList(eachProductBean.getStr("PRODUCT_DEVELOPER_ID"));
                for (String eachAccountDeptId : accountDeptIdList) {
                    if (developerIdList.contains(eachAccountDeptId)) {
                        productIdList.add(eachProductBean.getStr("JE_PRODUCT_MANAGE_ID"));
                        break;
                    }
                }
            }
        }

        StringBuffer sb = new StringBuffer();
        //启用了三员管理
        if("1".equals(GlobalExtendedContext.getContextKey("switch"))){
            sb.append(" AND JE_RBAC_ROLE_ID NOT IN ('" + AUTI_MANAGER_ROLE + "','" + SECURITY_MANAGER_ROLE + "','" + SYSTEM_MANAGER_ROLE + "')");
        }
        if (roleOrFolderIds == null || roleOrFolderIds.length == 0) {
            sb.append(" AND ROLE_DEVELOP = '" + (develop ? "1" : "0") + "'");
            sb.append(" AND JE_RBAC_ROLE_ID != 'ROOT'");
            if (develop) {
                sb.append(" AND (SY_PRODUCT_ID IN (" + StringUtil.buildArrayToString(productIdList) + ") OR JE_RBAC_ROLE_ID = 'productRoleId' OR JE_RBAC_ROLE_ID = 'platformRoleId')");
            }
        } else {
            sb.append(" AND ROLE_DEVELOP = '" + (develop ? "1" : "0") + "'");
            if (develop) {
                sb.append(" AND (SY_PRODUCT_ID IN (" + StringUtil.buildArrayToString(productIdList) + ") OR JE_RBAC_ROLE_ID = 'productRoleId' OR JE_RBAC_ROLE_ID = 'platformRoleId')");
            }
            sb.append(" AND (");
            for (int i = 0; i < roleOrFolderIds.length; i++) {
                if (i != 0) {
                    sb.append(" OR ");
                }
                sb.append(" SY_PATH LIKE '" + roleOrFolderIds[i] + "%'");
            }
            sb.append(")");
        }

        sb.append(" ORDER BY SY_TREEORDERINDEX ASC");

        long time = System.currentTimeMillis();
        List<Map<String, Object>> beanList = metaService.selectSql(ConditionsWrapper.builder().table("JE_RBAC_ROLE").apply(sb.toString()));
        logger.info("查询角色树时间消耗：" + (System.currentTimeMillis() - time));
        for (Map<String, Object> eachBean : beanList) {
            JSONTreeNode node = null;
            if (roleOrFolderIds == null || roleOrFolderIds.length == 0) {
                if ("ROOT".equals(eachBean.get("SY_PARENT"))) {
                    node = buildTreeNode(template, rootNode.getId(), eachBean);
                }
            } else {
                for (String eachId : roleOrFolderIds) {
                    if (eachId.equals(eachBean.get("JE_RBAC_ROLE_ID"))) {
                        node = buildTreeNode(template, rootNode.getId(), eachBean);
                    }
                }
            }
            if (node != null) {
                rootNode.getChildren().add(node);
            }
        }

        //递归形成树形结构
        for (JSONTreeNode eachNode : rootNode.getChildren()) {
            recursiveJsonTreeNode(template, eachNode, beanList);
        }

        return rootNode;
    }

    @Override
    public JSONTreeNode buildRoleTreeByQuery(boolean develop, BaseMethodArgument param) {
        Query query = param.buildQuery();
        ConditionsWrapper conditionsWrapper = query.buildWrapper();
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        DynaBean table = beanService.getResourceTable("JE_RBAC_ROLE");
        List<DynaBean> columns = (List<DynaBean>) table.get(BeanService.KEY_TABLE_COLUMNS);
        JSONTreeNode template = beanService.buildJSONTreeNodeTemplate(columns);
        String accountId = SecurityUserHolder.getCurrentAccountId();
        List<DynaBean> accountDeptBeanList = metaService.select("JE_RBAC_ACCOUNTDEPT", ConditionsWrapper.builder().eq("ACCOUNTDEPT_ACCOUNT_ID", accountId));
        List<String> accountDeptIdList = new ArrayList<>();
        for (int i = 0; accountDeptBeanList != null && !accountDeptBeanList.isEmpty() && i < accountDeptBeanList.size(); i++) {
            accountDeptIdList.add(accountDeptBeanList.get(i).getStr("JE_RBAC_ACCOUNTDEPT_ID"));
        }

        List<DynaBean> productList = metaResourceService.selectByTableCodeAndNativeQuery("JE_PRODUCT_MANAGE", NativeQuery.build());
        List<String> productIdList = new ArrayList<>();
        List<String> developerIdList;
        for (DynaBean eachProductBean : productList) {
            if (!Strings.isNullOrEmpty(eachProductBean.getStr("PRODUCT_DEVELOPER_ID"))) {
                developerIdList = Splitter.on(",").splitToList(eachProductBean.getStr("PRODUCT_DEVELOPER_ID"));
                for (String eachAccountDeptId : accountDeptIdList) {
                    if (developerIdList.contains(eachAccountDeptId)) {
                        productIdList.add(eachProductBean.getStr("JE_PRODUCT_MANAGE_ID"));
                        break;
                    }
                }
            }
        }

        StringBuffer sb = new StringBuffer();
        sb.append(" AND ROLE_DEVELOP = '" + (develop ? "1" : "0") + "'");
        sb.append(" AND JE_RBAC_ROLE_ID != 'ROOT'");
        if (develop) {
            sb.append(" AND (SY_PRODUCT_ID IN (" + StringUtil.buildArrayToString(productIdList) + ") OR JE_RBAC_ROLE_ID = 'productRoleId')");
        }

        sb.append(" ORDER BY SY_TREEORDERINDEX ASC");

        long time = System.currentTimeMillis();
        List<Map<String, Object>> beanList = metaService.selectSql(conditionsWrapper.table("JE_RBAC_ROLE").apply(sb.toString()));
        logger.info("查询角色树时间消耗：" + (System.currentTimeMillis() - time));
        for (Map<String, Object> eachBean : beanList) {
            JSONTreeNode node = null;
            if ("ROOT".equals(eachBean.get("SY_PARENT"))) {
                node = buildTreeNode(template, rootNode.getId(), eachBean);
            }
            if (node != null) {
                rootNode.getChildren().add(node);
            }
        }

        for (Map<String, Object> eachBean : beanList) {
            if (rootNode.getChildren().size() > 0) {
                boolean isHave = false;
                for (JSONTreeNode treeNode : rootNode.getChildren()) {
                    if (String.valueOf(eachBean.get("SY_PATH")).contains(treeNode.getNodePath()) || treeNode.getId().equals(eachBean.get("JE_RBAC_ROLE_ID"))) {
                        isHave = true;
                        break;
                    }
                }
                if (!isHave) {
                    JSONTreeNode node = buildTreeNode(template, "ROOT", eachBean);
                    rootNode.getChildren().add(node);
                }
            } else {
                JSONTreeNode node = buildTreeNode(template, "ROOT", eachBean);
                rootNode.getChildren().add(node);
            }
        }

        //递归形成树形结构
        for (JSONTreeNode eachNode : rootNode.getChildren()) {
            recursiveJsonTreeNode(template, eachNode, beanList);
        }

        return rootNode;
    }

    @Override
    public void importAccountByAccounts(String roleId, String strData) throws AccountException {
        if (Strings.isNullOrEmpty(strData)) {
            return;
        }
        JSONArray dataArray = JSONArray.parseArray(strData);
        JSONObject departmentUsersObject;
        for (int i = 0; i < dataArray.size(); i++) {
            departmentUsersObject = dataArray.getJSONObject(i);
            importAccountByAccounts(roleId, departmentUsersObject.getString("syOrgId"), departmentUsersObject.getString("departmentId"), departmentUsersObject.getString("accountId"));
        }
        permissionLoadService.reloadRolePermCache(Lists.newArrayList(roleId), false);
        permissionLoadService.reloadDevelopRolePermCache(Lists.newArrayList(roleId));
    }

    public void importAccountByAccounts(String roleId, String syOrgId, String departmentId, String accountId) throws AccountException {
        DynaBean roleBean = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .eq("JE_RBAC_ROLE_ID", roleId));
        if (roleBean == null) {
            throw new AccountException("不存在的角色！");
        }
        DynaBean departmentBean = null;
        DynaBean orgBean = metaService.selectOne("JE_RBAC_ORG", ConditionsWrapper.builder().eq("JE_RBAC_ORG_ID", syOrgId));
        if (OrgType.DEPARTMENT_ORG_ID.getCode().equals(orgBean.getStr("JE_RBAC_ORG_ID"))) {
            departmentBean = metaService.selectOne("JE_RBAC_DEPARTMENT", ConditionsWrapper.builder().eq("JE_RBAC_DEPARTMENT_ID", departmentId));
            if (departmentBean == null) {
                throw new AccountException("不存在的部门！");
            }
        }
        DynaBean accountBean = metaService.selectOne("JE_RBAC_ACCOUNT", ConditionsWrapper.builder().eq("JE_RBAC_ACCOUNT_ID", accountId));
        if (accountBean == null) {
            throw new AccountException("不存在的账号！");
        }
        //查询该账号部门信息是否存在，不存在则新增
        DynaBean accountDeptRoletBean = metaService.selectOne("JE_RBAC_ACCOUNTROLE", ConditionsWrapper.builder()
                .eq("ACCOUNTROLE_ROLE_ID", roleId)
                .eq("ACCOUNTROLE_DEPT_ID", departmentId)
                .eq("ACCOUNTROLE_ACCOUNT_ID", accountId));
        if (accountDeptRoletBean == null) {
            //查询该账号部门主分关系
            DynaBean userDeptBean = metaService.selectOne("JE_RBAC_VDEPTUSER", ConditionsWrapper.builder().eq("JE_RBAC_DEPARTMENT_ID", departmentId).eq("JE_RBAC_USER_ID", accountBean.getStr("USER_ASSOCIATION_ID")));
            DynaBean accountDeptRoleTempBean = new DynaBean("JE_RBAC_ACCOUNTROLE", false);
            accountDeptRoleTempBean.set("ACCOUNTROLE_DEPT_ID", departmentId);
            accountDeptRoleTempBean.set("ACCOUNTROLE_DEPT_NAME", departmentBean == null ? orgBean.getStr("ORG_NAME") : departmentBean.getStr("DEPARTMENT_NAME"));
            accountDeptRoleTempBean.set("ACCOUNTROLE_MAIN_CODE", userDeptBean == null ? "" : userDeptBean.getStr("DEPTUSER_MAIN_CODE"));
            accountDeptRoleTempBean.set("ACCOUNTROLE_ACCOUNT_ID", accountId);
            accountDeptRoleTempBean.set("ACCOUNTROLE_ROLE_ID", roleId);
            accountDeptRoleTempBean.set("ACCOUNTROLE_ROLE_NAME", roleBean.getStr("ROLE_NAME"));
            accountDeptRoleTempBean.set("SY_CREATETIME", DateUtils.formatDateTime(new Date()));
            commonService.buildModelCreateInfo(accountBean);
            metaService.insert(accountDeptRoleTempBean);
        }
        //如果存在产品信息  去架构管理方案类产品 同步人员
        if (Strings.isNullOrEmpty(roleBean.getStr("SY_PRODUCT_ID"))) {
            return;
        }
        DynaBean dynaBean = metaResourceService.selectOne("JE_PRODUCT_MANAGE", NativeQuery.build().eq("JE_PRODUCT_MANAGE_ID", roleBean.getStr("SY_PRODUCT_ID")), "");
        if (dynaBean == null) {
            return;
        }
        String developerIds = dynaBean.getStr("PRODUCT_DEVELOPER_ID");
        String developers = dynaBean.getStr("PRODUCT_DEVELOPER");
        List<DynaBean> accountDeptBeanList = metaService.select("JE_RBAC_VUSERQUERY", ConditionsWrapper.builder()
                .eq("ACCOUNT_ID", accountId).eq("DEPARTMENT_ID", departmentId));
        if (accountDeptBeanList == null || accountDeptBeanList.isEmpty()) {
            return;
        }
        String accountdeptId = accountDeptBeanList.get(0).getStr("JE_RBAC_ACCOUNTDEPT_ID");
        String userName = accountDeptBeanList.get(0).getStr("USER_NAME");
        if (developerIds.contains(accountdeptId)) {
            return;
        }
        if (Strings.isNullOrEmpty(developerIds)) {
            metaResourceService.executeSql("update JE_PRODUCT_MANAGE set PRODUCT_DEVELOPER_ID = '" + accountdeptId + "',PRODUCT_DEVELOPER = '" + userName + "' where JE_PRODUCT_MANAGE_ID = '" + roleBean.getStr("SY_PRODUCT_ID") + "'");
        } else {
            metaResourceService.executeSql("update JE_PRODUCT_MANAGE set PRODUCT_DEVELOPER_ID = '" + (developerIds + "," + accountdeptId) + "' ,PRODUCT_DEVELOPER = '" + (developers + "," + userName) + "' where JE_PRODUCT_MANAGE_ID = '" + roleBean.getStr("SY_PRODUCT_ID") + "'");
        }
    }

    private void recursiveJsonTreeNode(JSONTreeNode template, JSONTreeNode rootNode, List<Map<String, Object>> list) {
        if (list == null || list.isEmpty()) {
            return;
        }

        JSONTreeNode treeNode;
        for (Map<String, Object> eachBean : list) {
            if (rootNode.getId().equals(eachBean.get("SY_PARENT"))) {
                treeNode = buildTreeNode(template, rootNode.getId(), eachBean);
                rootNode.getChildren().add(treeNode);
            }
        }

        if (rootNode.getChildren() == null || rootNode.getChildren().isEmpty()) {
            rootNode.setLeaf(true);
            return;
        }

        rootNode.setLeaf(false);

        for (JSONTreeNode eachNode : rootNode.getChildren()) {
            recursiveJsonTreeNode(template, eachNode, list);
        }

    }

    private String getString(Object obj) {
        if (obj == null) {
            return null;
        }
        return obj.toString();
    }

    /**
     * 构建树形节点
     *
     * @param template     模板
     * @param parentNodeId 父节点ID
     * @param bean         当前bean
     * @return
     */
    private JSONTreeNode buildTreeNode(JSONTreeNode template, String parentNodeId, Map<String, Object> bean) {
        JSONTreeNode node = new JSONTreeNode();
        node.setId(bean.get("JE_RBAC_ROLE_ID").toString());
        node.setParent(parentNodeId);
        node.setLeaf(true);
        if (StringUtil.isNotEmpty(template.getText())) {
            node.setText(getString(bean.get(template.getText())));
        }
        if (StringUtil.isNotEmpty(template.getCode())) {
            node.setCode(getString(bean.get(template.getCode())));
        }
        //节点信息
        if (StringUtil.isNotEmpty(template.getNodeInfo())) {
            node.setNodeInfo(getString(bean.get(template.getNodeInfo())));
        }
        //节点信息类型
        if (StringUtil.isNotEmpty(template.getNodeInfoType())) {
            node.setNodeInfoType(getString(bean.get(template.getNodeInfoType())));
        }
        //节点类型
        if (StringUtil.isNotEmpty(template.getNodeType())) {
            node.setNodeType(getString(bean.get(template.getNodeType())));
        }
        //节点路径
        if (StringUtil.isNotEmpty(template.getNodePath())) {
            node.setNodePath(getString(bean.get(template.getNodePath())));
        }
        //是否禁用
        if (StringUtil.isNotEmpty(template.getDisabled())) {
            node.setDisabled(getString(bean.get(template.getDisabled())));
        }
        //树形排序
        if (StringUtil.isNotEmpty(template.getTreeOrderIndex())) {
            node.setTreeOrderIndex(getString(bean.get(template.getTreeOrderIndex())));
        }
        //节点类型
        if (StringUtil.isNotEmpty(template.getNodeType())) {
            node.setNodeType(getString(bean.get(template.getNodeType())));
        }
        //图标样式
        if (StringUtil.isNotEmpty(template.getIcon())) {
            node.setIcon(getString(bean.get(template.getIcon())));
        }
        //是否禁用
        if (StringUtil.isNotEmpty(template.getDisabled())) {
            node.setDisabled(getString(bean.get(template.getDisabled())));
        } else {
            node.setDisabled("0");
        }
        //描述
        if (StringUtil.isNotEmpty(template.getDescription())) {
            node.setDescription(getString(bean.get(template.getDescription())));
        }
        //排序
        if (StringUtil.isNotEmpty(template.getOrderIndex())) {
            node.setOrderIndex(bean.get(template.getOrderIndex()) + "");
        }
        node.setBean(bean);
        return node;
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, AccountException.class})
    public void importAccountByUsers(String roleId, String strData) throws AccountException {
        if (Strings.isNullOrEmpty(strData)) {
            return;
        }
        JSONArray dataArray = JSONArray.parseArray(strData);
        JSONObject departmentUsersObject;
        for (int i = 0; i < dataArray.size(); i++) {
            departmentUsersObject = dataArray.getJSONObject(i);
            String sysOrderIndex = departmentUsersObject.getString("sysOrderIndex");
            if (departmentUsersObject != null && Strings.isNullOrEmpty(sysOrderIndex)) {
                int userOrderCount = -1;
                List<Map<String, Object>> userOrderList = metaService.selectSql("SELECT MAX(SY_ORDERINDEX) AS MAX_COUNT FROM JE_RBAC_ACCOUNTROLE WHERE ACCOUNTROLE_ROLE_ID={0}", roleId);
                if (userOrderList.size() > 0) {
                    userOrderCount = Integer.valueOf(userOrderList.get(0).get("MAX_COUNT").toString());
                }
                sysOrderIndex = (userOrderCount + 1) + "";
            }
            importAccountByUsers(roleId, departmentUsersObject.getString("departmentId"), departmentUsersObject.getString("userIds"), sysOrderIndex);
        }
        permissionLoadService.reloadRolePermCache(Lists.newArrayList(roleId), false);
        permissionLoadService.reloadDevelopRolePermCache(Lists.newArrayList(roleId));
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, AccountException.class})
    public void importAccountUserSysOrderIdex(String roleId, String strData) throws AccountException {
        if (Strings.isNullOrEmpty(strData)) {
            return;
        }
        JSONArray dataArray = JSONArray.parseArray(strData);
        JSONObject departmentUsersObject;
        for (int i = 0; i < dataArray.size(); i++) {
            departmentUsersObject = dataArray.getJSONObject(i);
            updateAccountSysOrderIndex(roleId, departmentUsersObject.getString("departmentId"), departmentUsersObject.getString("userId"), departmentUsersObject.getString("sysOrderIndex"));
        }
        permissionLoadService.reloadRolePermCache(Lists.newArrayList(roleId), false);
        permissionLoadService.reloadDevelopRolePermCache(Lists.newArrayList(roleId));
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, AccountException.class})
    public void removeAccountByUsers(String roleId, String strData) throws AccountException {
        if (Strings.isNullOrEmpty(strData)) {
            return;
        }
        JSONArray dataArray = JSONArray.parseArray(strData);
        JSONObject departmentUsersObject;
        for (int i = 0; i < dataArray.size(); i++) {
            departmentUsersObject = dataArray.getJSONObject(i);
            removeAccountByUsers(roleId, departmentUsersObject.getString("departmentId"), departmentUsersObject.getString("userIds"));
        }
    }

    @Transactional(rollbackFor = {RuntimeException.class, AccountException.class})
    public void updateAccountSysOrderIndex(String roleId, String departmentId, String userId, String sysOrderIndex) throws AccountException {
        DynaBean accountBean = metaService.selectOne("JE_RBAC_ACCOUNT", ConditionsWrapper.builder().in("USER_ASSOCIATION_ID", userId));
        if (accountBean != null) {
            metaService.executeSql("UPDATE JE_RBAC_ACCOUNTROLE SET SY_ORDERINDEX={0} WHERE ACCOUNTROLE_ROLE_ID={1} AND ACCOUNTROLE_DEPT_ID={2} AND ACCOUNTROLE_ACCOUNT_ID={3}", sysOrderIndex, roleId, departmentId, accountBean.getStr("JE_RBAC_ACCOUNT_ID"));
        }
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, AccountException.class})
    public void importAccountByUsers(String roleId, String departmentId, String userIds, String sysOrderIndex) throws AccountException {
        List<String> userIdList = Splitter.on(",").splitToList(userIds);
        List<DynaBean> deptUserBeanList = metaService.select("JE_RBAC_VDEPTUSER", ConditionsWrapper.builder()
                .eq("JE_RBAC_DEPARTMENT_ID", departmentId).in("JE_RBAC_USER_ID", userIdList));
        if (deptUserBeanList == null || deptUserBeanList.isEmpty()) {
            throw new AccountException("不存在的部门人员！");
        }

        List<DynaBean> accountBeanList = metaService.select("JE_RBAC_ACCOUNT", ConditionsWrapper.builder().in("USER_ASSOCIATION_ID", userIdList));
        List<String> accountIdList = new ArrayList<>();
        Map<String, DynaBean> hasAccountMap = new HashMap<>();
        for (DynaBean eachAccountBean : accountBeanList) {
            hasAccountMap.put(eachAccountBean.getStr("USER_ASSOCIATION_ID"), eachAccountBean);
            accountIdList.add(eachAccountBean.getStr("JE_RBAC_ACCOUNT_ID"));
        }

        String defaultPassword = metaSystemSettingRpcService.requireSettingValue("JE_SYS_PASSWORD");
        if (Strings.isNullOrEmpty(defaultPassword)) {
            throw new AccountException("系统设置默认密码为空！");
        }

        DynaBean departmentBean = metaService.selectOne("JE_RBAC_DEPARTMENT", ConditionsWrapper.builder().eq("JE_RBAC_DEPARTMENT_ID", departmentId));
        if (departmentBean == null) {
            throw new AccountException("不存在的部门！");
        }

        DynaBean roleBean = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .eq("JE_RBAC_ROLE_ID", roleId));
        if (roleBean == null) {
            throw new AccountException("不存在的角色！");
        }

        List<DynaBean> accountDeptRoleBeanList = metaService.select("JE_RBAC_ACCOUNTROLE", ConditionsWrapper.builder()
                .eq("ACCOUNTROLE_DEPT_ID", departmentId).eq("ACCOUNTROLE_ROLE_ID", roleId).in("ACCOUNTROLE_ACCOUNT_ID", accountIdList));

        DynaBean orgBean = metaService.selectOne("JE_RBAC_ORG", ConditionsWrapper.builder().eq("JE_RBAC_ORG_ID", departmentBean.getStr("SY_ORG_ID")));

        String accountId;
        String createTime = DateUtils.formatDateTime(new Date());
        for (DynaBean eachUserBean : deptUserBeanList) {
            if (!hasAccountMap.containsKey(eachUserBean.getStr("JE_RBAC_USER_ID"))) {
                accountId = JEUUID.uuid();
                DynaBean accountBean = new DynaBean("JE_RBAC_ACCOUNT", true);
                accountBean.set("JE_RBAC_ACCOUNT_ID", accountId);
                accountBean.set("ACCOUNT_NAME", eachUserBean.getStr("USER_NAME"));
                accountBean.set("ACCOUNT_CODE", eachUserBean.getStr("USER_CODE"));
                accountBean.set("ACCOUNT_OPENID", JEUUID.uuid());
                accountBean.set("ACCOUNT_PASSWORD", SecureUtil.md5(defaultPassword));
                accountBean.set("ACCOUNT_PHONE", eachUserBean.getStr("USER_PHONE"));
                accountBean.set("ACCOUNT_MAIL", eachUserBean.getStr("USER_MAIL"));
                accountBean.set("ACCOUNT_SEX", eachUserBean.getStr("USER_SEX_CODE"));
                accountBean.set("ACCOUNT_AVATAR", eachUserBean.getStr("USER_AVATAR"));
                accountBean.set("USER_ASSOCIATION_ID", eachUserBean.getStr("JE_RBAC_USER_ID"));
                accountBean.set("SY_TENANT_ID", eachUserBean.getStr("SY_TENANT_ID"));
                accountBean.set("SY_TENANT_NAME", eachUserBean.getStr("SY_TENANT_NAME"));
                accountBean.set("ACCOUNT_REMARK", "通过部门人员创建！");
                accountBean.set("SY_ORG_ID", orgBean.getStr("JE_RBAC_ORG_ID"));
                accountBean.set("SY_ORG_NAME", orgBean.getStr("ORG_NAME"));
                accountBean.set("SY_STATUS", eachUserBean.getStr("SY_STATUS"));
                accountBean.set("USER_STATUS", eachUserBean.getStr("USER_EMPLOYEE_STATUS"));
                accountBean.set("ACCOUNT_LOCKED_STATUS", "1");
                commonService.buildModelCreateInfo(accountBean);
                metaService.insert(accountBean);
            } else {
                accountId = hasAccountMap.get(eachUserBean.getStr("JE_RBAC_USER_ID")).getStr("JE_RBAC_ACCOUNT_ID");
            }

            DynaBean accountDeptBean = metaService.selectOne("JE_RBAC_ACCOUNTDEPT", ConditionsWrapper.builder()
                    .eq("ACCOUNTDEPT_DEPT_ID", departmentId).eq("ACCOUNTDEPT_ACCOUNT_ID", accountId));
            if (accountDeptBean == null) {
                accountDeptBean = new DynaBean("JE_RBAC_ACCOUNTDEPT", false);
                accountDeptBean.set("ACCOUNTDEPT_DEPT_ID", departmentId);
                accountDeptBean.set("ACCOUNTDEPT_DEPT_NAME", departmentBean.getStr("DEPARTMENT_NAME"));
                accountDeptBean.set("SY_CREATETIME", DateUtils.formatDateTime(new Date()));
                accountDeptBean.set("ACCOUNTDEPT_ACCOUNT_ID", accountId);
                accountDeptBean.set("SY_COMPANY_ID", departmentBean.getStr("SY_COMPANY_ID"));
                accountDeptBean.set("SY_COMPANY_NAME", departmentBean.getStr("SY_COMPANY_NAME"));
                accountDeptBean.set("SY_GROUP_COMPANY_ID", departmentBean.getStr("SY_GROUP_COMPANY_ID"));
                accountDeptBean.set("SY_GROUP_COMPANY_NAME", departmentBean.getStr("SY_GROUP_COMPANY_NAME"));
                commonService.buildModelCreateInfo(accountDeptBean);
                metaService.insert(accountDeptBean);
            }

            if (accountDeptRoleBeanList == null || accountDeptRoleBeanList.isEmpty()) {
                DynaBean accountDeptRoleTempBean = new DynaBean("JE_RBAC_ACCOUNTROLE", false);
                accountDeptRoleTempBean.set("ACCOUNTROLE_DEPT_ID", departmentId);
                accountDeptRoleTempBean.set("ACCOUNTROLE_DEPT_NAME", departmentBean.getStr("DEPARTMENT_NAME"));
                accountDeptRoleTempBean.set("ACCOUNTROLE_MAIN_CODE", eachUserBean.getStr("DEPTUSER_MAIN_CODE"));
                accountDeptRoleTempBean.set("ACCOUNTROLE_ACCOUNT_ID", accountId);
                accountDeptRoleTempBean.set("ACCOUNTROLE_ROLE_ID", roleId);
                accountDeptRoleTempBean.set("ACCOUNTROLE_ROLE_NAME", roleBean.getStr("ROLE_NAME"));
                accountDeptRoleTempBean.set("SY_ORDERINDEX", sysOrderIndex);
                commonService.buildModelCreateInfo(accountDeptRoleTempBean);
                metaService.insert(accountDeptRoleTempBean);
            } else {
                for (DynaBean eachAccountDeptRoleBean : accountDeptRoleBeanList) {
                    if (eachAccountDeptRoleBean.getStr("ACCOUNTROLE_DEPT_ID").equals(departmentId)
                            && eachAccountDeptRoleBean.getStr("ACCOUNTROLE_ROLE_ID").equals(roleId)
                            && eachAccountDeptRoleBean.getStr("ACCOUNTROLE_ACCOUNT_ID").equals(accountId)) {
                        //若该角色部门账号数据已存在，检查sysOrderIndex 不一致 则更新
                        if (!(Strings.isNullOrEmpty(eachAccountDeptRoleBean.getStr("SY_ORDERINDEX")) ? "" : eachAccountDeptRoleBean.getStr("SY_ORDERINDEX")).equals(sysOrderIndex)) {
                            metaService.executeSql("UPDATE JE_RBAC_ACCOUNTROLE SET SY_ORDERINDEX={0} WHERE ACCOUNTROLE_ROLE_ID={1} AND ACCOUNTROLE_DEPT_ID={2} AND ACCOUNTROLE_ACCOUNT_ID={3}", sysOrderIndex, roleId, departmentId, accountId);
                        }
                        continue;
                    }
                    DynaBean accountDeptRoleTempBean = new DynaBean("JE_RBAC_ACCOUNTROLE", false);
                    accountDeptRoleTempBean.set("ACCOUNTROLE_DEPT_ID", departmentId);
                    accountDeptRoleTempBean.set("ACCOUNTROLE_DEPT_NAME", departmentBean.getStr("DEPARTMENT_NAME"));
                    accountDeptRoleTempBean.set("ACCOUNTROLE_ACCOUNT_ID", accountId);
                    accountDeptRoleTempBean.set("ACCOUNTROLE_ROLE_ID", roleId);
                    accountDeptRoleTempBean.set("ACCOUNTROLE_ROLE_NAME", roleBean.getStr("ROLE_NAME"));
                    accountDeptRoleTempBean.set("SY_ORDERINDEX", sysOrderIndex);
                    //accountDeptRoleTempBean.set("SY_CREATETIME", DateUtils.formatDateTime(new Date()));
                    commonService.buildModelCreateInfo(accountDeptRoleTempBean);
                    metaService.insert(accountDeptRoleTempBean);
                }
            }

        }

        List<DynaBean> realUserBeans = metaService.select("JE_RBAC_USER", ConditionsWrapper.builder().in("JE_RBAC_USER_ID", userIdList));
        for (DynaBean eachUserBean : realUserBeans) {
            if (!Strings.isNullOrEmpty(eachUserBean.getStr("USER_ROLE_ID")) && eachUserBean.getStr("USER_ROLE_ID").indexOf(roleId) != -1) {
                continue;
            }
            if (Strings.isNullOrEmpty(eachUserBean.getStr("USER_ROLE_ID"))) {
                eachUserBean.set("USER_ROLE_ID", roleId);
                eachUserBean.set("USER_ROLE_NAME", roleBean.getStr("ROLE_NAME"));
            } else {
                eachUserBean.set("USER_ROLE_ID", eachUserBean.getStr("USER_ROLE_ID") + "," + roleId);
                eachUserBean.set("USER_ROLE_NAME", eachUserBean.getStr("USER_ROLE_NAME") + "," + roleBean.getStr("ROLE_NAME"));
            }
            metaService.update(eachUserBean);
        }
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, AccountException.class})
    public void removeAccountByUsers(String roleId, String departmentId, String userIds) throws AccountException {
        List<String> userIdList = Splitter.on(",").splitToList(userIds);
        List<DynaBean> accountDeptBeanList = metaService.select("JE_RBAC_VACCOUNTDEPT", ConditionsWrapper.builder()
                .eq("ACCOUNTDEPT_DEPT_ID", departmentId).in("USER_ASSOCIATION_ID", userIdList));
        List<String> accountIdList = new ArrayList<>();
        for (DynaBean eachAccountBean : accountDeptBeanList) {
            accountIdList.add(eachAccountBean.getStr("JE_RBAC_ACCOUNT_ID"));
        }
        removeAccountRole(roleId, departmentId, accountIdList);
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, AccountException.class})
    public void importAccountByDepartments(String roleId, String departments) throws AccountException {
        List<String> deptIdList = Splitter.on(",").splitToList(departments);
        List<DynaBean> deptUserBeanList = metaService.select("JE_RBAC_VDEPTUSER", ConditionsWrapper.builder()
                .in("JE_RBAC_DEPARTMENT_ID", deptIdList));

        Map<String, List<String>> departmentUsersMap = new HashMap<>();
        List<String> inList;
        for (DynaBean eachBean : deptUserBeanList) {
            if (departmentUsersMap.containsKey(eachBean.getStr("JE_RBAC_DEPARTMENT_ID"))) {
                inList = departmentUsersMap.get(eachBean.getStr("JE_RBAC_DEPARTMENT_ID"));
            } else {
                inList = new ArrayList<>();
                departmentUsersMap.put(eachBean.getStr("JE_RBAC_DEPARTMENT_ID"), inList);
            }
            inList.add(eachBean.getStr("JE_RBAC_USER_ID"));
        }

        for (Map.Entry<String, List<String>> eachEntry : departmentUsersMap.entrySet()) {
            importAccountByUsers(roleId, eachEntry.getKey(), Joiner.on(",").join(eachEntry.getValue()), "");
        }

        permissionLoadService.reloadRolePermCache(Lists.newArrayList(roleId), false);
        permissionLoadService.reloadDevelopRolePermCache(Lists.newArrayList(roleId));

    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, AccountException.class})
    public void removeAccountByDepartments(String roleId, String departments) throws AccountException {
        List<String> deptIdList = Splitter.on(",").splitToList(departments);
        List<DynaBean> deptUserBeanList = metaService.select("JE_RBAC_VDEPTUSER", ConditionsWrapper.builder()
                .in("JE_RBAC_DEPARTMENT_ID", deptIdList));
        Map<String, List<String>> departmentUsersMap = new HashMap<>();
        List<String> inList;
        for (DynaBean eachBean : deptUserBeanList) {
            if (departmentUsersMap.containsKey(eachBean.getStr("JE_RBAC_DEPARTMENT_ID"))) {
                inList = departmentUsersMap.get(eachBean.getStr("JE_RBAC_DEPARTMENT_ID"));
            } else {
                inList = new ArrayList<>();
                departmentUsersMap.put(eachBean.getStr("JE_RBAC_DEPARTMENT_ID"), inList);
            }
            inList.add(eachBean.getStr("JE_RBAC_USER_ID"));
        }
        for (Map.Entry<String, List<String>> eachEntry : departmentUsersMap.entrySet()) {
            removeAccountByUsers(roleId, eachEntry.getKey(), Joiner.on(",").join(eachEntry.getValue()));
        }
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, AccountException.class})
    public void importAccountByOrgs(String roleId, String orgId, String ids) throws AccountException {
        List<String> accountIdList = Splitter.on(",").splitToList(ids);
        DynaBean orgBean = metaService.selectOne("JE_RBAC_ORG", ConditionsWrapper.builder().eq("JE_RBAC_ORG_ID", orgId));
        if (orgBean == null) {
            throw new NotOrgException("不存在此机构，请确认！");
        }

        DynaBean roleBean = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .eq("JE_RBAC_ROLE_ID", roleId));
        if (roleBean == null) {
            throw new AccountException("不存在的角色！");
        }

        List<DynaBean> accountBeanList = metaService.select("JE_RBAC_ACCOUNT", ConditionsWrapper.builder().in("JE_RBAC_ACCOUNT_ID", accountIdList));

        //取出所有的账号数据，去角色账号部门表中查找，若查不到，则新增
        for (String accountId : accountIdList) {
            DynaBean accountDeptRoleBean = metaService.selectOne("JE_RBAC_ACCOUNTROLE", ConditionsWrapper.builder()
                    .in("ACCOUNTROLE_DEPT_ID", orgBean.getStr("JE_RBAC_ORG_ID"))
                    .eq("ACCOUNTROLE_ROLE_ID", roleId)
                    .in("ACCOUNTROLE_ACCOUNT_ID", accountId));
            if (accountDeptRoleBean == null) {
                DynaBean accountDeptRoleTempBean = new DynaBean("JE_RBAC_ACCOUNTROLE", false);
                accountDeptRoleTempBean.set("ACCOUNTROLE_ACCOUNT_ID", accountId);
                accountDeptRoleTempBean.set("ACCOUNTROLE_DEPT_NAME", orgBean.getStr("ORG_NAME"));
                accountDeptRoleTempBean.set("ACCOUNTROLE_DEPT_ID", orgBean.getStr("JE_RBAC_ORG_ID"));
                accountDeptRoleTempBean.set("ACCOUNTROLE_ROLE_ID", roleId);
                accountDeptRoleTempBean.set("ACCOUNTROLE_ROLE_NAME", roleBean.getStr("ROLE_NAME"));
                accountDeptRoleTempBean.set("SY_CREATETIME", DateUtils.formatDateTime(new Date()));
                metaService.insert(accountDeptRoleTempBean);
            }
        }

        //获取到映射的资源表和资源表主键
        String tableCode = orgBean.getStr("ORG_RESOURCETABLE_CODE");
        String tableIdCode = orgBean.getStr("ORG_FIELD_PK");
        if (Strings.isNullOrEmpty(tableCode) || Strings.isNullOrEmpty(tableIdCode)) {
            throw new AccountException("Can't find the tableCode or pk code from the org mapping!");
        }

        //获取映射字段，更新人员角色
        String accountRoleIdField = orgBean.getStr("ORG_ROLEFIELD_ID");
        String accountRoleNameField = orgBean.getStr("ORG_ROLEFIELD_NAME");

        List<String> userIdList = new ArrayList<>();
        for (DynaBean eachAccountBean : accountBeanList) {
            userIdList.add(eachAccountBean.getStr("USER_ASSOCIATION_ID"));
        }
        List<DynaBean> userBeans = metaService.select(tableCode, ConditionsWrapper.builder().in(tableIdCode, userIdList));

        //更新机构用户拥有的角色
        for (DynaBean eachUserBean : userBeans) {
            if (!Strings.isNullOrEmpty(eachUserBean.getStr(accountRoleIdField)) && eachUserBean.getStr(accountRoleIdField).indexOf(roleId) != -1) {
                continue;
            }
            if (Strings.isNullOrEmpty(eachUserBean.getStr(accountRoleIdField))) {
                eachUserBean.set(accountRoleIdField, roleId);
                eachUserBean.set(accountRoleNameField, roleBean.getStr("ROLE_NAME"));
            } else {
                eachUserBean.set(accountRoleIdField, eachUserBean.getStr(accountRoleIdField) + "," + roleId);
                eachUserBean.set(accountRoleNameField, eachUserBean.getStr(accountRoleNameField) + "," + roleBean.getStr("ROLE_NAME"));
            }
            metaService.update(eachUserBean);
        }

        permissionLoadService.reloadRolePermCache(Lists.newArrayList(roleId), false);
        permissionLoadService.reloadDevelopRolePermCache(Lists.newArrayList(roleId));

    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, AccountException.class})
    public void removeAccountByOrgs(String roleId, String orgId, String ids) throws AccountException {
        removeAccountByUsers(roleId, ids, ids);
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, AccountException.class})
    public void removeAccountRole(String roleId, Map<String, List<String>> accountMap) throws AccountException {
        List<String> accountIdList = new ArrayList<>();
        for (Map.Entry<String, List<String>> eachEntry : accountMap.entrySet()) {
            removeAccountRole(roleId, eachEntry.getKey(), eachEntry.getValue());
            accountIdList.addAll(eachEntry.getValue());
        }
        permissionLoadService.removeAccountPermsCache(accountIdList);
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, AccountException.class})
    public void removeAccountRole(String roleId, String departmentId, List<String> accountIdList) throws AccountException {
        DynaBean roleBean = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder().eq("JE_RBAC_ROLE_ID", roleId));
        if (roleBean == null) {
            throw new AccountException("账号角色不存在！");
        }

        List<DynaBean> accountBeanList = metaService.select("JE_RBAC_VACCOUNTDEPT", ConditionsWrapper.builder()
                .eq("ACCOUNTDEPT_DEPT_ID", departmentId)
                .in("JE_RBAC_ACCOUNT_ID", accountIdList));

        Map<String, List<String>> orgUserListMap = new HashMap<>();
        List<String> userIdList;
        for (DynaBean eachAccountBean : accountBeanList) {
            if (orgUserListMap.containsKey(eachAccountBean.getStr("SY_ORG_ID"))) {
                userIdList = orgUserListMap.get(eachAccountBean.getStr("SY_ORG_ID"));
            } else {
                userIdList = new ArrayList<>();
                orgUserListMap.put(eachAccountBean.getStr("SY_ORG_ID"), userIdList);
            }
            userIdList.add(eachAccountBean.getStr("USER_ASSOCIATION_ID"));
        }

        List<DynaBean> orgBeanList = metaService.select("JE_RBAC_ORG", ConditionsWrapper.builder().in("JE_RBAC_ORG_ID", orgUserListMap.keySet()));
        if (orgBeanList == null || orgBeanList.isEmpty()) {
            throw new AccountException("账号机构不存在！");
        }

        for (DynaBean eachOrgBean : orgBeanList) {
            //获取到映射的资源表和资源表主键
            String tableCode = eachOrgBean.getStr("ORG_RESOURCETABLE_CODE");
            String tableIdCode = eachOrgBean.getStr("ORG_FIELD_PK");
            if (Strings.isNullOrEmpty(tableCode) || Strings.isNullOrEmpty(tableIdCode)) {
                throw new AccountException("Can't find the tableCode or pk code from the org mapping!");
            }

            //获取映射字段，账号名称、账号编码、账号手机、账号邮箱、账号头像
            String accountRoleIdField = eachOrgBean.getStr("ORG_ROLEFIELD_ID");
            String accountRoleNameField = eachOrgBean.getStr("ORG_ROLEFIELD_NAME");

            List<DynaBean> userBeanList = metaService.select(tableCode, ConditionsWrapper.builder().in(tableIdCode, orgUserListMap.get(eachOrgBean.getStr("JE_RBAC_ORG_ID"))));
            for (DynaBean eachUserBean : userBeanList) {
                if (Strings.isNullOrEmpty(eachUserBean.getStr(accountRoleIdField))) {
                    continue;
                }
                if (!eachUserBean.getStr(accountRoleIdField).contains(roleId)) {
                    continue;
                }
                //修改外部机构用户已剔除的角色信息
                List<String> indexData = new ArrayList<>();
                List<String> jgIdList = Arrays.asList(eachUserBean.getStr(accountRoleIdField).split(ArrayUtils.SPLIT));
                if (jgIdList.indexOf(roleId) >= 0) {
                    //记录要删除的下标
                    indexData.add(jgIdList.indexOf(roleId) + "");
                }
                eachUserBean.set(accountRoleIdField, removeRoleIdMsg(eachUserBean.getStr(accountRoleIdField), roleId));
                eachUserBean.set(accountRoleNameField, removeRoleNameMsg(eachUserBean.getStr(accountRoleNameField), indexData));

                metaService.update(eachUserBean);
            }
        }

        metaService.delete("JE_RBAC_ACCOUNTROLE", ConditionsWrapper.builder()
                .eq("ACCOUNTROLE_DEPT_ID", departmentId)
                .eq("ACCOUNTROLE_ROLE_ID", roleId)
                .in("ACCOUNTROLE_ACCOUNT_ID", accountIdList));
        //如果存在产品信息  去架构管理方案类产品 同步人员
        if (Strings.isNullOrEmpty(roleBean.getStr("SY_PRODUCT_ID"))) {
            return;
        }
        DynaBean dynaBean = metaResourceService.selectOne("JE_PRODUCT_MANAGE", NativeQuery.build().eq("JE_PRODUCT_MANAGE_ID", roleBean.getStr("SY_PRODUCT_ID")), "");
        if (dynaBean == null) {
            return;
        }

        String developerIds = dynaBean.getStr("PRODUCT_DEVELOPER_ID");
        String developeds = dynaBean.getStr("PRODUCT_DEVELOPER");
        for (String accountId : accountIdList) {
            List<DynaBean> accountDeptBeanList = metaService.select("JE_RBAC_VUSERQUERY", ConditionsWrapper.builder()
                    .eq("ACCOUNT_ID", accountId).eq("DEPARTMENT_ID", departmentId));
            if (accountDeptBeanList == null || accountDeptBeanList.isEmpty()) {
                return;
            }
            String accountdeptId = accountDeptBeanList.get(0).getStr("JE_RBAC_ACCOUNTDEPT_ID");
            String userName = accountDeptBeanList.get(0).getStr("USER_NAME");
            if (!developerIds.contains(accountdeptId)) {
                continue;
            }
            if (!Strings.isNullOrEmpty(developerIds)) {
                if (developerIds.endsWith(accountdeptId)) {
                    developerIds = developerIds.replaceAll("," + accountdeptId, "");
                    developeds = developeds.replaceAll("," + userName, "");
                } else {
                    developerIds = developerIds.replaceAll(accountdeptId + ",", "");
                    developeds = developeds.replaceAll(userName + ",", "");
                }
                metaResourceService.executeSql("update JE_PRODUCT_MANAGE set PRODUCT_DEVELOPER_ID = '" + developerIds + "' ,PRODUCT_DEVELOPER = '" + developeds + "'where JE_PRODUCT_MANAGE_ID = '" + roleBean.getStr("SY_PRODUCT_ID") + "'");
            }
        }
    }

    @Override
    public void syncUpdateReferencesRoleName(String roleId, String roleName) {
        rbacUserService.updateUserRoleName(roleId, roleName);
        rbacAccountService.updateRoleName(roleId, roleName);
        rbacGrantOrgService.updateUserRoleName(roleId, roleName);
    }

    private String removeSplittedStr(String splittedStr, String id) {
        List<String> splitList = new ArrayList<>(Splitter.on(",").splitToList(splittedStr));
        if (splitList.contains(id)) {
            splitList.remove(id);
        }
        return Joiner.on(",").join(splitList);
    }

    public String removeRoleIdMsg(String idStr, String roleId) {
        List<String> jgIdList = Arrays.asList(idStr.split(ArrayUtils.SPLIT));
        List<String> newGgIdList = new ArrayList(jgIdList);
        List<String> indexData = new ArrayList<>();
        if (jgIdList.indexOf(roleId) >= 0) {
            //记录要删除的下标
            indexData.add(jgIdList.indexOf(roleId) + "");
            newGgIdList.remove(roleId);
        }
        return StringUtils.join(newGgIdList, ",");
    }

    public String removeRoleNameMsg(String nameStr, List<String> indexData) {
        //名称
        List<String> jgNameList = Arrays.asList(nameStr.split(ArrayUtils.SPLIT));
        List<String> newGgNameList = new ArrayList(jgNameList);
        for (String eachIndex : indexData) {
            newGgNameList.remove(Integer.parseInt(eachIndex));
        }
        return StringUtils.join(newGgNameList, ",");
    }

}